package com.cctc.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
import org.springframework.dao.PessimisticLockingFailureException;

/**
 * @Name ConcurrentOperationExecutor
 * @Description: 并发操作 [失败重试] 执行器
 * @Author: lichao
 * @Email: li2chao@126.com
 * @Date: 2024-01-19 11:11:10
 **/
@Aspect
public class ConcurrentOperationExecutor implements Ordered {
    // 默认最大重试次数: 3次
    private static final int DEFAULT_MAX_RETRIES = 3;
    // 最大重试次数
    private int maxRetries = DEFAULT_MAX_RETRIES;
    // 切面执行顺序（优先级），设置得比事务切面高，我们希望每次重试都是一个新的事务
    private int order = 1;

    public void setMaxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public int getMaxRetries() {
        return maxRetries;
    }

    @Override
    public int getOrder() {
        return order;
    }

    /**
     * [目标方法] 代理行动 - 执行并发操作
     *
     * @param joinPoint 织入点
     * @return java.lang.Object [目标方法] 返回值
     * @author lichao
     * @email li2chao@126.com
     * @date 2024/01/19 11:15:49
     */
    public Object doConcurrentOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        int attemptNums = 0;
        PessimisticLockingFailureException lockingFailureException;
        // 如果目标方法执行失败，则反复重试，直到达到最大尝试次数再抛出异常。
        do {
            attemptNums++;
            try {
                return joinPoint.proceed();
            } catch (PessimisticLockingFailureException ex) {
                lockingFailureException = ex;
            }
        } while (attemptNums <= this.maxRetries);
        throw lockingFailureException;
    }


}

